/*
 * array_enh.js
 *
 * Copyright (C) 2006 - OS3 srl - http://www.os3.it
 *
 * Written by: Fabio Rotondo - fabio.rotondo@os3.it
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation;
 * version 2 of the License ONLY.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTE: this is the GPL version of the library. If you want to include this 
 *       library inside a CLOSED SOURCE / PROPRIETARY software, you need 
 *       to purchase a COMMERCIAL LICENSE. See http://www.os3.it/license/
 *       for more info.
 */

// {{{ base docs
/**
Array Enhancements
==================

LiWE extends the basic JavaScript ``Array`` class with many new functions.
Here there is the complete list and description.

**/
// }}}

// {{{ Array.prototype.toSourceString ( include_funcs )
/**
.. function:: Array.prototype.toSourceString ( [ include_funcs ] )

	Use ``toSourceString`` to convert an Array to a JSON-friendly object rappresentation.
	By default, this function does not include function definitions. Set ``include_funcs`` to ``true`` to
	allow this.

	This method returns a string rappresentation of the current array.

	:param include_funcs: set this to ``true`` if you want your array rappresentation to include also custom functions.
			      This is ``false`` by default.

	:rtype: a string rappresenting the current array
**/
Array.prototype.toSourceString = function ( include_funcs )
{
	var s = '{';
	var k, v;
	var is_first = true;

	for ( k in this )
	{
		if ( ( typeof ( this [ k ] ) == 'function' ) && ( ! include_funcs ) ) continue;

		if ( ! is_first ) s += ", ";
		s += "'" + k + "' : '" + this [ k ] + "'";
		is_first = false;
	}

	s += "}";

	return s;
};
// }}}

// PUBLIC: count
Array.prototype.count = function ()
{
	var k;
	var res = 0;
	
	for ( k in this )
	{
		if ( ( typeof ( this [ k ] ) == 'function' ) ) continue;
		if ( k == '__arr' ) continue;
		res ++;
	}

	return res;
};

// PUBLIC: fromObject
Array.fromObject = function ( a, include_funcs )
{
	var arr = new Array ();
	var k, v;

	for ( k in a ) 
	{
		if ( ( ! include_funcs ) && ( typeof ( a [ k ] ) == 'function' ) ) continue;

		arr [ k ] = a [ k ];
	}

	return arr;
};

// PUBLIC: fromForm
Array.fromForm = function ( form_id, max_depth )
{
	var arr = new Array ();
	var f = $( form_id ); // document.getElementById ( form_id );
	
	if ( ! max_depth ) max_depth = 0;

	_form_add_elems ( f, arr, max_depth, 0 );

	return arr;
};

Object.fromForm = function ( form_id, max_depth )
{
	var arr = {};
	var f = document.getElementById ( form_id );
	
	if ( ! max_depth ) max_depth = 0;

	_form_add_elems ( f, arr, max_depth, 0 );

	return arr;
};

// PUBLIC: find
Array.prototype.find = function ( key, case_sens, include_funcs )
{
	var k;
	var c = 0;

	if ( ! case_sens ) key = key.toLowerCase ();

	for ( k in this )
	{
		if ( ( typeof ( this [ k ] ) == 'function' ) && ( ! include_funcs ) ) continue;

		k = this [ k ];
		if ( ! case_sens ) k = k.toLowerCase ();
		if ( k == key ) return c;
			
		c++;
	}

	return -1;
};

// PUBLIC: toObject
Array.toObject = function ( arr )
{
	var res = {};
	var k;

	for ( k in arr )
	{
		if ( ( typeof ( arr [ k ] ) == 'function' ) ) continue;
		
		res [ k ] = arr [ k ];
	}

	return res;
};

// PUBLIC: del
Array.prototype.del = function ( pos, how_many )
{
	if ( ! how_many ) how_many = 1;

	var to_del = Array();

	var start = pos;
	var stop = pos + how_many;

	var k, count = -1, i;
	for ( k in this )
	{
		count++;

		if ( count < start ) 	  continue;
		else if ( count >= stop ) break;

		to_del.push ( k );
	}

	for ( i = 0; i < to_del.length; i++ )
	{
		delete this [ to_del [ i ] ];
	}
};

// PUBLIC: delKey
Array.prototype.delKey = function ( k )
{
	delete this [ k ];
};


if ( Array.prototype.indexOf == null )
{
	Array.prototype.indexOf = function ( item )
	{
		var t, l = this.length;
		for ( t = 0; t < l; t ++ )
			if ( this [ t ] == item ) return t;
		return -1;
	};
}


function _form_add_elems( node, arr, max_depth, curr_depth )
{
	var inps, sels, txts, t, n;

	inps = node.getElementsByTagName ( "input" );
	sels = node.getElementsByTagName ( "select" );
	txts = node.getElementsByTagName ( "textarea" );

	for ( t = 0; t < inps.length; t ++ )
	{
		n = inps [ t ];
		if ( ( ( n.type == 'radio' ) || ( n.type == 'checkbox' ) ) && ( n.checked == false ) ) continue;
		arr [ n.name ] = n.value;
	}

	for ( t = 0; t < sels.length; t ++ ) arr [ sels [ t ].name ] = sels [ t ].value;
	for ( t = 0; t < txts.length; t ++ ) arr [ txts [ t ].name ] = txts [ t ].value;
}


/* Implement array.push for browsers which don't support it natively. 
   Copyright 2005 Mark Wubben 
*/
if ( Array.prototype.push == null )
{
	Array.prototype.push = function() 
	{
		for( var i = 0; i < arguments.length; i++ )
			this [ this.length ] = arguments [ i ];

		return this.length;
	};
}

